home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / raid / devRaidLog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  16.1 KB  |  690 lines

  1. /* 
  2.  * devRaidLog.c --
  3.  *
  4.  *    Implements logging and recovery for raid devices.
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/raid/devRaidLog.c,v 1.11 92/06/25 17:21:05 eklee Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include "sync.h"
  21. #include <sprite.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include "devRaid.h"
  25. #include "devRaidDisk.h"
  26. #include "devRaidLog.h"
  27. #include "bit.h"
  28. #include "miscutil.h"
  29. #include "devRaidProto.h"
  30.  
  31. /*
  32.  * Forward declaration.
  33.  */
  34. void Raid_UpdateLog();
  35. void Raid_FlushLog();
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  * Raid_AttachLogDevice --
  41.  *
  42.  * Results:
  43.  *
  44.  * Side effects:
  45.  *
  46.  *----------------------------------------------------------------------
  47.  */
  48. ReturnStatus
  49. Raid_AttachLogDevice(raidPtr, type, unit, offset)
  50.     Raid        *raidPtr;
  51.     int            type, unit, offset;
  52. {
  53.     RaidLog        *logPtr = &raidPtr->log;
  54.  
  55.     logPtr->logDev.type = type;
  56.     logPtr->logDev.unit = unit;
  57.     logPtr->logDevOffset = offset;
  58.     logPtr->logHandlePtr = Dev_BlockDeviceAttach(&logPtr->logDev);
  59.     if (logPtr->logHandlePtr == (DevBlockDeviceHandle *) NIL) {
  60.     return FAILURE;
  61.     }
  62.     return SUCCESS;
  63. }
  64.  
  65. /*
  66.  *----------------------------------------------------------------------
  67.  *
  68.  * Raid_InitLog --
  69.  *
  70.  * Results:
  71.  *
  72.  * Side effects:
  73.  *
  74.  *----------------------------------------------------------------------
  75.  */
  76. void
  77. Raid_InitLog(raidPtr)
  78.     Raid        *raidPtr;
  79. {
  80.     RaidLog        *logPtr = &raidPtr->log;
  81.  
  82.     Sync_SemInitDynamic(&logPtr->mutex, "RAID log mutex");
  83.     logPtr->enabled = 0;
  84.     logPtr->busy = 0;
  85.     logPtr->diskLockVec = (int *) malloc(VecSize(raidPtr));
  86.     bzero((char *) logPtr->diskLockVec, VecSize(raidPtr));
  87.     logPtr->lockVec = (int *) malloc(VecSize(raidPtr));
  88.     bzero((char *) logPtr->lockVec, VecSize(raidPtr));
  89.     logPtr->numStripeLocked = 0;
  90.     bzero((char *) logPtr->lockVec, VecSize(raidPtr));
  91.     logPtr->logDevEndOffset = logPtr->logDevOffset + LogSize(raidPtr);
  92. #ifdef TESTING
  93.     Sync_CondInit(&logPtr->flushed);
  94. #endif TESTING
  95. }
  96.  
  97. /*
  98.  *----------------------------------------------------------------------
  99.  *
  100.  * Raid_EnableLog --
  101.  *
  102.  * Results:
  103.  *
  104.  * Side effects:
  105.  *
  106.  *----------------------------------------------------------------------
  107.  */
  108. void
  109. Raid_EnableLog(raidPtr)
  110.     Raid *raidPtr;
  111. {
  112.     raidPtr->log.enabled = 1;
  113. }
  114.  
  115. /*
  116.  *----------------------------------------------------------------------
  117.  *
  118.  * Raid_DisableLog --
  119.  *
  120.  * Results:
  121.  *
  122.  * Side effects:
  123.  *
  124.  *----------------------------------------------------------------------
  125.  */
  126. void
  127. Raid_DisableLog(raidPtr)
  128.     Raid *raidPtr;
  129. {
  130.     raidPtr->log.enabled = 0;
  131. }
  132.  
  133. /*
  134.  *----------------------------------------------------------------------
  135.  *
  136.  * Raid_SaveParam --
  137.  *    
  138.  * Results:
  139.  *
  140.  * Side effects:
  141.  *
  142.  *----------------------------------------------------------------------
  143.  */
  144. static ReturnStatus
  145. Raid_SaveParam(raidPtr)
  146.     Raid    *raidPtr;
  147. {
  148.     ReturnStatus status;
  149.     status = Raid_DevWriteInt(raidPtr->log.logHandlePtr, ParamLoc(raidPtr),
  150.         6, raidPtr->numRow, raidPtr->numCol, raidPtr->logBytesPerSector,
  151.         raidPtr->sectorsPerStripeUnit, raidPtr->stripeUnitsPerDisk,
  152.         (int) raidPtr->parityConfig);
  153.     return status;
  154. }
  155.  
  156. /*
  157.  *----------------------------------------------------------------------
  158.  *
  159.  * ComputeRaidParam --
  160.  *
  161.  *    Compute redundant but convenient information.
  162.  *
  163.  * Results:
  164.  *
  165.  * Side effects:
  166.  *
  167.  *----------------------------------------------------------------------
  168.  */
  169. static void
  170. ComputeRaidParam(raidPtr)
  171.     Raid    *raidPtr;
  172. {
  173.     /*
  174.      * Compute redundant but convenient information.
  175.      */
  176.     if (raidPtr->parityConfig == 'S') {
  177.     raidPtr->numDataCol = raidPtr->numCol;
  178.     } else {
  179.     raidPtr->numDataCol = raidPtr->numCol - 1;
  180.     }
  181.     switch (raidPtr->parityConfig) {
  182.     case 'X': case 'x': case 'f':
  183.     raidPtr->stripeUnitsPerDisk -=
  184.         raidPtr->stripeUnitsPerDisk % raidPtr->numCol;
  185.         raidPtr->dataStripeUnitsPerDisk =
  186.                 (raidPtr->stripeUnitsPerDisk * raidPtr->numDataCol) /
  187.         raidPtr->numCol;
  188.     break;
  189.     default:
  190.     raidPtr->dataStripeUnitsPerDisk = raidPtr->stripeUnitsPerDisk;
  191.     break;
  192.     }
  193.     raidPtr->groupsPerArray = raidPtr->numRow / raidPtr->rowsPerGroup;
  194.     raidPtr->numSector  = (unsigned) raidPtr->numRow * raidPtr->numDataCol
  195.         * raidPtr->sectorsPerStripeUnit * raidPtr->stripeUnitsPerDisk;
  196.     raidPtr->numStripe  = raidPtr->stripeUnitsPerDisk * raidPtr->numRow;
  197.     raidPtr->dataSectorsPerStripe =
  198.         raidPtr->numDataCol * raidPtr->sectorsPerStripeUnit;
  199.     raidPtr->sectorsPerDisk =
  200.         raidPtr->stripeUnitsPerDisk * raidPtr->sectorsPerStripeUnit;
  201.     raidPtr->bytesPerStripeUnit = raidPtr->sectorsPerStripeUnit <<
  202.         raidPtr->logBytesPerSector;
  203.     raidPtr->dataBytesPerStripe = raidPtr->dataSectorsPerStripe <<
  204.         raidPtr->logBytesPerSector;
  205.     raidPtr->bytesPerSector = 1 << raidPtr->logBytesPerSector;
  206. }
  207.  
  208. /*
  209.  *----------------------------------------------------------------------
  210.  *
  211.  * Raid_RestoreParam --
  212.  *    
  213.  * Results:
  214.  *
  215.  * Side effects:
  216.  *
  217.  *----------------------------------------------------------------------
  218.  */
  219. static ReturnStatus
  220. Raid_RestoreParam(raidPtr)
  221.     Raid    *raidPtr;
  222. {
  223.     int        parityConfig;
  224.     ReturnStatus status;
  225.  
  226.     status = Raid_DevReadInt(raidPtr->log.logHandlePtr, ParamLoc(raidPtr),
  227.         6, &raidPtr->numRow, &raidPtr->numCol, &raidPtr->logBytesPerSector,
  228.         &raidPtr->sectorsPerStripeUnit, &raidPtr->stripeUnitsPerDisk,
  229.         &parityConfig);
  230.     raidPtr->rowsPerGroup = raidPtr->numRow;
  231.     raidPtr->parityConfig = parityConfig;
  232.     ComputeRaidParam(raidPtr);
  233.     return status;
  234. }
  235.  
  236. /*
  237.  *----------------------------------------------------------------------
  238.  *
  239.  * Raid_SaveDisk --
  240.  *    
  241.  * Results:
  242.  *
  243.  * Side effects:
  244.  *
  245.  *----------------------------------------------------------------------
  246.  */
  247. ReturnStatus
  248. Raid_SaveDisk(raidPtr, col, row, type, unit, version, numValidSector)
  249.     Raid    *raidPtr;
  250.     int        col, row;
  251.     int        type, unit, version, numValidSector;
  252. {
  253.     ReturnStatus status;
  254.  
  255.     status = Raid_DevWriteInt(raidPtr->log.logHandlePtr,
  256.         DiskLoc(raidPtr, col, row),
  257.         4, type, unit, version, numValidSector);
  258.     return status;
  259. }
  260.  
  261. /*
  262.  *----------------------------------------------------------------------
  263.  *
  264.  * Raid_RestoreDisk --
  265.  *    
  266.  * Results:
  267.  *
  268.  * Side effects:
  269.  *
  270.  *----------------------------------------------------------------------
  271.  */
  272. static ReturnStatus
  273. Raid_RestoreDisk(raidPtr, col, row)
  274.     Raid    *raidPtr;
  275.     int        col, row;
  276. {
  277.     ReturnStatus status;
  278.     int         type, unit, version, numValidSector;
  279.  
  280.     status = Raid_DevReadInt(raidPtr->log.logHandlePtr,DiskLoc(raidPtr,col,row),
  281.         4, &type, &unit, &version, &numValidSector);
  282.     if (status != SUCCESS) {
  283.     return status;
  284.     }
  285.     raidPtr->disk[col][row] =
  286.         Raid_MakeDisk(col,row, type, unit, version, numValidSector);
  287.     if (raidPtr->disk[col][row] == (RaidDisk *) NIL) {
  288.     return FAILURE;
  289.     }
  290.     return SUCCESS;
  291. }
  292.  
  293. /*
  294.  *----------------------------------------------------------------------
  295.  *
  296.  * Raid_SaveLog --
  297.  *    
  298.  * Results:
  299.  *
  300.  * Side effects:
  301.  *
  302.  *----------------------------------------------------------------------
  303.  */
  304. ReturnStatus
  305. Raid_SaveLog(raidPtr)
  306.     Raid    *raidPtr;
  307. {
  308.     ReturnStatus    status;
  309.  
  310.     status = Raid_DevWriteSync(raidPtr->log.logHandlePtr, VecLoc(raidPtr),
  311.             (char *) raidPtr->log.diskLockVec, VecSize(raidPtr));
  312.     return status;
  313. }
  314.  
  315. /*
  316.  *----------------------------------------------------------------------
  317.  *
  318.  * Raid_RestoreLog --
  319.  *    
  320.  * Results:
  321.  *
  322.  * Side effects:
  323.  *
  324.  *----------------------------------------------------------------------
  325.  */
  326. ReturnStatus
  327. Raid_RestoreLog(raidPtr)
  328.     Raid    *raidPtr;
  329. {
  330.     ReturnStatus    status;
  331.  
  332.     status = Raid_DevReadSync(raidPtr->log.logHandlePtr, VecLoc(raidPtr),
  333.             (char *) raidPtr->log.diskLockVec, VecSize(raidPtr));
  334.     return status;
  335. }
  336.  
  337. /*
  338.  *----------------------------------------------------------------------
  339.  *
  340.  * Raid_ApplyLog --
  341.  *
  342.  * Results:
  343.  *
  344.  * Side effects:
  345.  *
  346.  *----------------------------------------------------------------------
  347.  */
  348. ReturnStatus
  349. Raid_ApplyLog(raidPtr)
  350.     Raid    *raidPtr;
  351. {
  352.     SyncControl        syncControl;
  353.     ReturnStatus    status;
  354.     int            stripeID;
  355.  
  356.     Raid_InitSyncControl(&syncControl);
  357.     for (stripeID = 0; stripeID < raidPtr->numStripe; stripeID++) {
  358.     if (Bit_IsClear(stripeID, raidPtr->log.diskLockVec)) {
  359.         continue;
  360.     }
  361.     Raid_StartSyncIO(&syncControl);
  362.     Raid_InitiateHardInit(raidPtr, stripeID, 1,
  363.         (void (*)()) Raid_SyncDoneProc, (ClientData) &syncControl,NULL);
  364.     status = Raid_WaitSyncIO(&syncControl);
  365.     if (status != SUCCESS) {
  366.         return status;
  367.     }
  368.     }
  369.     return SUCCESS;
  370. }
  371.  
  372. /*
  373.  *----------------------------------------------------------------------
  374.  *
  375.  * Raid_SaveState --
  376.  *    
  377.  * Results:
  378.  *
  379.  * Side effects:
  380.  *
  381.  *----------------------------------------------------------------------
  382.  */
  383. ReturnStatus
  384. Raid_SaveState(raidPtr)
  385.     Raid *raidPtr;
  386. {
  387.     int            col, row;
  388.     RaidDisk        *diskPtr;
  389.     ReturnStatus    status;
  390.  
  391.     status = Raid_SaveParam(raidPtr);
  392.     if (status != SUCCESS) {
  393.     return status;
  394.     }
  395.     for ( row = 0; row < raidPtr->numRow; row++ ) {
  396.         for ( col = 0; col < raidPtr->numCol; col++ ) {
  397.         diskPtr = raidPtr->disk[col][row];
  398.         status = Raid_SaveDisk(raidPtr, col, row,
  399.             diskPtr->device.type, diskPtr->device.unit,
  400.             diskPtr->version, diskPtr->numValidSector);
  401.         if (status != SUCCESS) {
  402.         return status;
  403.         }
  404.     }
  405.     }
  406.     MASTER_LOCK(&raidPtr->log.mutex);
  407.     bcopy((char *) raidPtr->log.lockVec, (char *) raidPtr->log.diskLockVec,
  408.         VecSize(raidPtr));
  409.     MASTER_UNLOCK(&raidPtr->log.mutex);
  410.     status = Raid_SaveLog(raidPtr);
  411.     return status;
  412. }
  413.  
  414. /*
  415.  *----------------------------------------------------------------------
  416.  *
  417.  * Raid_RestoreState --
  418.  *
  419.  * Results:
  420.  *
  421.  * Side effects:
  422.  *
  423.  *----------------------------------------------------------------------
  424.  */
  425. ReturnStatus
  426. Raid_RestoreState(raidPtr, type, unit, offset)
  427.     Raid        *raidPtr;
  428.     int            type, unit, offset;
  429. {
  430.     int            col, row;
  431.     ReturnStatus    status;
  432.  
  433.     status = Raid_AttachLogDevice(raidPtr, type, unit, offset);
  434.     if (status != SUCCESS) {
  435.     return status;
  436.     }
  437.     status = Raid_RestoreParam(raidPtr);
  438.     if (status != SUCCESS) {
  439.     return status;
  440.     }
  441.     /*
  442.      * Restore disk state and attach disks.
  443.      */
  444.     raidPtr->disk = (RaidDisk ***)
  445.         malloc((unsigned)raidPtr->numCol * sizeof(RaidDisk **));
  446.     for ( col = 0; col < raidPtr->numCol; col++ ) {
  447.     raidPtr->disk[col] = (RaidDisk **)
  448.         malloc((unsigned)raidPtr->numRow * sizeof(RaidDisk *));
  449.     bzero((char*)raidPtr->disk[col],raidPtr->numRow*sizeof(RaidDisk *));
  450.     }
  451.     for ( row = 0; row < raidPtr->numRow; row++ ) {
  452.         for ( col = 0; col < raidPtr->numCol; col++ ) {
  453.         status = Raid_RestoreDisk(raidPtr, col, row);
  454.         if (status != SUCCESS) {
  455.         return status;
  456.         }
  457.     }
  458.     }
  459.     /*
  460.      * Restore and apply log.
  461.      */
  462.     Raid_InitLog(raidPtr);
  463.     status = Raid_RestoreLog(raidPtr);
  464.     if (status != SUCCESS) {
  465.     return status;
  466.     }
  467.     status = Raid_ApplyLog(raidPtr);
  468.     if (status != SUCCESS) {
  469.     return status;
  470.     }
  471.  
  472.     raidPtr->state = RAID_VALID;
  473.     return SUCCESS;
  474. }
  475.  
  476.  
  477. /*
  478.  *----------------------------------------------------------------------
  479.  *
  480.  * Raid_Configure --
  481.  *
  482.  *    Configure raid device from configuration buffer.
  483.  *
  484.  * Results:
  485.  *    None.
  486.  *
  487.  * Side effects:
  488.  *    Allocates and initializes data structures for raid device.
  489.  *
  490.  *----------------------------------------------------------------------
  491.  */
  492.  
  493. /* static */ ReturnStatus
  494. Raid_Configure(raidPtr, charBuf)
  495.     Raid        *raidPtr;
  496.     char        *charBuf;
  497. {
  498.     char        *charBufPtr;
  499.     int            col, row;
  500.     int            type, unit;
  501.     int            logType, logUnit, logOffset;
  502.     int            numScanned;
  503.     RaidDisk        *diskPtr;
  504.     ReturnStatus    status;
  505.  
  506.     charBufPtr = charBuf;
  507.     /*
  508.      * Skip comments.
  509.      */
  510.     for (;;) {
  511.         if (!ScanLine(&charBufPtr, charBuf)) {
  512.         return FAILURE;
  513.         }
  514.         if (charBuf[0] != '#') {
  515.             break;
  516.         }
  517.     }
  518.  
  519.     /*
  520.      * Read dimensions of raid device.
  521.      */
  522.     numScanned = sscanf(charBuf, "%d %d %d %d %d %c %d %d %d",
  523.              &raidPtr->numRow,
  524.             &raidPtr->numCol,
  525.             &raidPtr->logBytesPerSector,
  526.             &raidPtr->sectorsPerStripeUnit,
  527.             &raidPtr->stripeUnitsPerDisk,
  528.             &raidPtr->parityConfig,
  529.             &logType,
  530.             &logUnit,
  531.             &logOffset);
  532.     raidPtr->rowsPerGroup = raidPtr->numRow;
  533.     if (numScanned != 9) {
  534.     return FAILURE;
  535.     }
  536.     ComputeRaidParam(raidPtr);
  537.  
  538.     /*
  539.      * Attach log device.
  540.      */
  541.     if (raidPtr->parityConfig != 'S') {
  542.     status = Raid_AttachLogDevice(raidPtr, logType, logUnit, logOffset);
  543.     if (status != SUCCESS) {
  544.         return status;
  545.     }
  546.     Raid_InitLog(raidPtr);
  547.     }
  548.  
  549.     /*
  550.      * Attach RaidDisk's.
  551.      */
  552.     raidPtr->disk = (RaidDisk ***)
  553.         malloc((unsigned)raidPtr->numCol * sizeof(RaidDisk **));
  554.     for ( col = 0; col < raidPtr->numCol; col++ ) {
  555.     raidPtr->disk[col] = (RaidDisk **)
  556.         malloc((unsigned)raidPtr->numRow * sizeof(RaidDisk *));
  557.     bzero((char*)raidPtr->disk[col],raidPtr->numRow*sizeof(RaidDisk *));
  558.     }
  559.     for ( row = 0; row < raidPtr->numRow; row++ ) {
  560.         for ( col = 0; col < raidPtr->numCol; col++ ) {
  561.         if (!ScanWord(&charBufPtr, charBuf)) {
  562.         return FAILURE;
  563.         }
  564.         type = atoi(charBuf);
  565.         if (!ScanWord(&charBufPtr, charBuf)) {
  566.         return FAILURE;
  567.         }
  568.         unit = atoi(charBuf);
  569.         diskPtr = Raid_MakeDisk(col, row, type, unit, 1,
  570.             raidPtr->sectorsPerDisk);
  571.         if (diskPtr == (RaidDisk *) NIL) {
  572.         printf("Could not attach disk %d %d\n", type, unit);
  573.         return FAILURE;
  574.         }
  575.         raidPtr->disk[col][row] = diskPtr;
  576.     }
  577.     }
  578.  
  579.     raidPtr->state = RAID_VALID;
  580.     return SUCCESS;
  581. }
  582.  
  583. /*
  584.  *----------------------------------------------------------------------
  585.  *
  586.  * Raid_FlushLog --
  587.  *
  588.  *    Flush log to disk.
  589.  *
  590.  * Results:
  591.  *
  592.  * Side effects:
  593.  *
  594.  *----------------------------------------------------------------------
  595.  */
  596.  
  597. void
  598. Raid_FlushLog(raidPtr)
  599.     Raid *raidPtr;
  600. {
  601.     MASTER_LOCK(&raidPtr->log.mutex);
  602.     if (!raidPtr->log.enabled) {
  603.     MASTER_UNLOCK(&raidPtr->log.mutex);
  604.     return;
  605.     }
  606.     if (raidPtr->log.busy) {
  607.     /*
  608.      * Wait for log flush in operation to finish.
  609.      */
  610.     Sync_MasterWait(&raidPtr->log.flushed, &raidPtr->log.mutex, FALSE);
  611.     /*
  612.      * If someone else is flushing my log, we just need to wait for it
  613.      * to finish.  Otherwise, I'll have to flush it myself.
  614.      */
  615.     if (raidPtr->log.busy) {
  616.         Sync_MasterWait(&raidPtr->log.flushed, &raidPtr->log.mutex, FALSE);
  617.         MASTER_UNLOCK(&raidPtr->log.mutex);
  618.         return;
  619.     }
  620.     }
  621.     raidPtr->log.busy = 1;
  622.     MASTER_UNLOCK(&raidPtr->log.mutex);
  623.  
  624.     while (Raid_SaveLog(raidPtr) != SUCCESS) {
  625.     printf("Error writing log\n");
  626.     Raid_WaitTime(10000);
  627.     }
  628.  
  629.     MASTER_LOCK(&raidPtr->log.mutex);
  630.     raidPtr->log.busy = 0;
  631.     Sync_MasterBroadcast(&raidPtr->log.flushed);
  632.     MASTER_UNLOCK(&raidPtr->log.mutex);
  633. }
  634.  
  635.  
  636. /*
  637.  *----------------------------------------------------------------------
  638.  *
  639.  * Raid_LogStripe --
  640.  *
  641.  *    Make an entry in the specified log.
  642.  *
  643.  * Results:
  644.  *    None.
  645.  *
  646.  * Side effects:
  647.  *
  648.  *----------------------------------------------------------------------
  649.  */
  650. #ifdef TESTING
  651. #define NUM_LOG_STRIPE 2
  652. #else
  653. #define NUM_LOG_STRIPE 100
  654. #endif
  655.  
  656. void
  657. Raid_LogStripe(raidPtr, stripeID)
  658.     Raid        *raidPtr;
  659.     int            stripeID;
  660. {
  661.     MASTER_LOCK(&raidPtr->log.mutex);
  662.     Bit_Set(stripeID, raidPtr->log.lockVec);
  663.     if (Bit_IsSet(stripeID, raidPtr->log.diskLockVec)) {
  664.     MASTER_UNLOCK(&raidPtr->log.mutex);
  665.     return;
  666.     }
  667.     Bit_Set(stripeID, raidPtr->log.diskLockVec);
  668.     /*
  669.      * Occasionally update log.
  670.      */
  671.     raidPtr->log.numStripeLocked++;
  672.     if (raidPtr->log.numStripeLocked % NUM_LOG_STRIPE == 0) {
  673.     bcopy((char *) raidPtr->log.lockVec, (char *) raidPtr->log.diskLockVec,
  674.         VecSize(raidPtr));
  675.     }
  676.     MASTER_UNLOCK(&raidPtr->log.mutex);
  677.  
  678.     Raid_FlushLog(raidPtr);
  679. }
  680.  
  681. void
  682. Raid_UnlogStripe(raidPtr, stripeID)
  683.     Raid        *raidPtr;
  684.     int            stripeID;
  685. {
  686.     MASTER_LOCK(&raidPtr->log.mutex);
  687.     Bit_Clear(stripeID, raidPtr->log.lockVec);
  688.     MASTER_UNLOCK(&raidPtr->log.mutex);
  689. }
  690.